/*
* ============================================================================
*  Name        : sea_engine.h
*  Part of     : Finite state machine framework
*  Description : Top level engine object
*  Version     : %version: %
*  
*
* ============================================================================
*/
/**
 * @file sea_engine.h
 * @brief
 * @ref sea::Engine
 *
 * @ingroup StateMachineFramework
 */
#if !defined( __sea_sm_engine_h__ )
#define __sea_sm_engine_h__

#include "sea_event.h"
#include "sea_timer_server.h"

namespace sea
{
    class Manager;

    /**
     * @class Engine sea_engine.h "sea_engine.h"
     * @brief 
     *   State Machine Engine keeps track of all state machines managers
     *
     * @ingroup StateMachineFramework
     */
    class Engine : public Object
    {
        friend class Manager;
        friend class StateMachine;
        friend class Timer;

    public:

        /**
         * Forse state machine engine to terminate. All state machines in all managers will get Ev_Sys_Teminate.
         * The function will wait for all managers/state machines to exit
         */
        static void terminate( );

    private:

        Engine( );
        ~Engine( );

        /**
         * Get engine. Create on first call.
         * 
         * @return Engine* Engine 
         */
        static sea::ref< Engine > engine( );

        /**
         * Create and launch new manager. 
         *
         * @param sync_op If true, no thread will be launched
         * @param parser If true no waiting on semaphore for the events
         * 
         * @return Manager* New manager
         */
        sea::ref< Manager > create_manager( bool sync_op, bool parser = false );

        /**
         * Remove manager - engine association
         *
         * @param manager Manager to be forgotten
         */
        void remove_manager( Manager* manager );

        /**
         * Get timer server
         * 
         * @return Engine* Engine 
         */
        TimerServer* timer_server( ){ return &m_timerServer; }

        /**
         * Get Engine's lock
         * 
         * @return OsMutex&
         */
        OsMutex* lock( ){ return &m_lock; }

    private:
        static Engine* m_engine;
        static OsMutex m_create_lock;
        OsMutex m_lock;
        TimerServer m_timerServer;

    };
}
#endif
